/*
  Part of the MasterTool3D project - http://code.google.com/p/master-tool-3d

  Copyright (c) 2011 Ingo Pueschl

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation, version 2.1.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General
  Public License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA
*/

package techjit.util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import techjit.util.RuntimeParams.ReleaseEnum;

public class ParamManager {

	// METHODS
	private static boolean getBooleanValue(String s) {
		boolean booleanValue = false;
		if (s.equals("0") || s.equals("false")) {
			booleanValue = false;
		} else if (s.equals("1") || s.equals("true")) {
			booleanValue = true;
		} else {
			LogManager
					.warningALL("Tried to set BooleanParam to invalid value.");
		}
		return booleanValue;
	}

	private static float getFloatValue(String s) {
		float floatValue = 0;
		try {
			floatValue = Float.parseFloat(s);
		} catch (NumberFormatException e) {
			LogManager.warningALL("Tried to set FloatParam to invalid value.");
			e.printStackTrace();
		}
		return floatValue;
	}

	private static int getIntValue(String s) {
		int intValue = 0;
		try {
			if (s.startsWith("0x")) {
				s = s.replaceFirst("0x", "");
				intValue = (int) Long.parseLong(s, 16);
			} else {
				intValue = Integer.parseInt(s);
			}
		} catch (NumberFormatException e) {
			LogManager.warningALL("Tried to set IntParam to invalid value.");
			e.printStackTrace();
		}
		return intValue;
	}

	public static void init() {
		if (LocalWorkspaceConstants.author == RP.AuthorsEnum.RELEASE) {
			RuntimeParams.release = ReleaseEnum.RELEASE;
		} else {
			switch (LocalWorkspaceConstants.author) {
			case CS:
				RuntimeParams.AUTHOR__CS = true;
				break;
			case ER:
				RuntimeParams.AUTHOR__ER = true;
				break;
			case HK:
				RuntimeParams.AUTHOR__HK = true;
				break;
			case IP:
				RuntimeParams.AUTHOR__IP = true;
				break;
			case JR:
				RuntimeParams.AUTHOR__JR = true;
				break;
			case TH:
				RuntimeParams.AUTHOR__TH = true;
				break;
			case TM:
				RuntimeParams.AUTHOR__TM = true;
				break;
			}
		}
	}

	private static void logError_fileInvalid() {
		LogManager.errorALL("Param file invalid.");
	}

	private static void processParam(String name, String value) {
		setValue(name, value);
	}

	private static void readFile() {
		String fileName = LocalWorkspaceConstants.REPOSITORY_PATH
				+ "SoftwareVisualizer/src/techjit/util/RuntimeParams";

		RP.AuthorsEnum txt = LocalWorkspaceConstants.SPECIFY_RUNTIME_PARAMS_TXT;
		switch (txt) {
		case MINE:
			switch (LocalWorkspaceConstants.author) {
			case CS:
				fileName += "CS.txt";
				break;
			case ER:
				fileName += "ER.txt";
				break;
			case HK:
				fileName += "HK.txt";
				break;
			case IP:
				fileName += "IP.txt";
				break;
			case JR:
				fileName += "JR.txt";
				break;
			case TH:
				fileName += "TH.txt";
				break;
			case TM:
				fileName += "TM.txt";
				break;
			default:
				LogManager
						.warningALL("The `author' field in `LocalWorkspaceConstants' is not specified correctly!");
				break;
			}
			break;
		case CS:
			fileName += "CS.txt";
			break;
		case ER:
			fileName += "ER.txt";
			break;
		case HK:
			fileName += "HK.txt";
			break;
		case IP:
			fileName += "IP.txt";
			break;
		case JR:
			fileName += "JR.txt";
			break;
		case TH:
			fileName += "TH.txt";
			break;
		case TM:
			fileName += "TM.txt";
			break;
		}

		try {
			BufferedReader reader = new BufferedReader(new FileReader(fileName));
			readLines(reader);
		} catch (IOException e) {
			e.printStackTrace();
			logError_fileInvalid();
		}
	}

	private static void readLines(BufferedReader reader) throws IOException {
		String line = "";
		while ((line = reader.readLine()) != null && !line.equals("")) {
			String name = readName(line);
			String value;
			if ((line = reader.readLine()) != null) {
				value = readValue(line);
			} else {
				break;
			}
			processParam(name, value);
		}
	}

	private static String readName(String line) {
		StringTokenizer tokenizer = new StringTokenizer(line);
		String name = "";
		try {
			name = tokenizer.nextToken();
		} catch (NoSuchElementException e) {
			e.printStackTrace();
			logError_fileInvalid();
		}
		return name;
	}

	private static String readValue(String line) {
		StringTokenizer tokenizer = new StringTokenizer(line);
		String value = "";
		try {
			if (tokenizer.nextToken().equals("=")) {
				value = tokenizer.nextToken();
			} else {
				logError_fileInvalid();
			}
		} catch (NoSuchElementException e) {
			e.printStackTrace();
			logError_fileInvalid();
		}
		return value;
	}

	private static void setValue(String name, String value) {
		// public static (.*) (.*) = (.*);
		// else if (name.equals("\2")) {#RP.\2 = get\1Value(value);#}
		// #
		// \r\n

		// <author>
		if (name.equals("AUTHOR__CS")) {
			RuntimeParams.AUTHOR__CS = getBooleanValue(value);
		} else if (name.equals("AUTHOR__ER")) {
			RuntimeParams.AUTHOR__ER = getBooleanValue(value);
		} else if (name.equals("AUTHOR__HK")) {
			RuntimeParams.AUTHOR__HK = getBooleanValue(value);
		} else if (name.equals("AUTHOR__IP")) {
			RuntimeParams.AUTHOR__IP = getBooleanValue(value);
		} else if (name.equals("AUTHOR__JR")) {
			RuntimeParams.AUTHOR__JR = getBooleanValue(value);
		} else if (name.equals("AUTHOR__TM")) {
			RuntimeParams.AUTHOR__TM = getBooleanValue(value);
		} else if (name.equals("AUTHOR__TH")) {
			RuntimeParams.AUTHOR__TH = getBooleanValue(value);
		}
		// </author>

		// <assembler>
		else if (name.equals("ASSEMBLER__CREATE_PACKAGES")) {
			RuntimeParams.ASSEMBLER__CREATE_PACKAGES = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_CLASSES")) {
			RuntimeParams.ASSEMBLER__CREATE_CLASSES = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_METHODS")) {
			RuntimeParams.ASSEMBLER__CREATE_METHODS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_INTERFACES")) {
			RuntimeParams.ASSEMBLER__CREATE_INTERFACES = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_CONSTRUCTORS")) {
			RuntimeParams.ASSEMBLER__CREATE_CONSTRUCTORS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_FIELDS")) {
			RuntimeParams.ASSEMBLER__CREATE_FIELDS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_PACKAGE_LABELS")) {
			RuntimeParams.ASSEMBLER__CREATE_PACKAGE_LABELS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_CLASS_LABELS")) {
			RuntimeParams.ASSEMBLER__CREATE_CLASS_LABELS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_INTERFACE_LABELS")) {
			RuntimeParams.ASSEMBLER__CREATE_INTERFACE_LABELS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_CONSTRUCTOR_LABELS")) {
			RuntimeParams.ASSEMBLER__CREATE_CONSTRUCTOR_LABELS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_METHOD_LABELS")) {
			RuntimeParams.ASSEMBLER__CREATE_METHOD_LABELS = getBooleanValue(value);
		} else if (name.equals("ASSEMBLER__CREATE_FIELD_LABELS")) {
			RuntimeParams.ASSEMBLER__CREATE_FIELD_LABELS = getBooleanValue(value);
		}
		// </assembler>

		// <collapsing>
		else if (name.equals("COLLAPSING__PACKAGES_EXCEPT_TOP")) {
			RuntimeParams.COLLAPSING__PACKAGES_EXCEPT_TOP = getBooleanValue(value);
		} else if (name.equals("COLLAPSING__CLASSES")) {
			RuntimeParams.COLLAPSING__CLASSES = getBooleanValue(value);
		} else if (name.equals("COLLAPSING__METHODS")) {
			RuntimeParams.COLLAPSING__METHODS = getBooleanValue(value);
		}
		// </collapsing>

		// <coordinateSystem.worldSystem>
		else if (name.equals("WORLD_SYSTEM__COORDINATE_SYSTEM_MAX_X_UNITS")) {
			RuntimeParams.WORLD_SYSTEM__COORDINATE_SYSTEM_MAX_X_UNITS = getFloatValue(value);
		} else if (name.equals("WORLD_SYSTEM__COORDINATE_SYSTEM_MAX_Y_UNITS")) {
			RuntimeParams.WORLD_SYSTEM__COORDINATE_SYSTEM_MAX_Y_UNITS = getFloatValue(value);
		} else if (name.equals("WORLD_SYSTEM__COORDINATE_SYSTEM_MAX_Z_UNITS")) {
			RuntimeParams.WORLD_SYSTEM__COORDINATE_SYSTEM_MAX_Z_UNITS = getFloatValue(value);
		} else if (name.equals("WORLD_SYSTEM__COORDINATE_SYSTEM_MIN_X_UNITS")) {
			RuntimeParams.WORLD_SYSTEM__COORDINATE_SYSTEM_MIN_X_UNITS = getFloatValue(value);
		} else if (name.equals("WORLD_SYSTEM__COORDINATE_SYSTEM_MIN_Y_UNITS")) {
			RuntimeParams.WORLD_SYSTEM__COORDINATE_SYSTEM_MIN_Y_UNITS = getFloatValue(value);
		} else if (name.equals("WORLD_SYSTEM__COORDINATE_SYSTEM_MIN_Z_UNITS")) {
			RuntimeParams.WORLD_SYSTEM__COORDINATE_SYSTEM_MIN_Z_UNITS = getFloatValue(value);
		}
		// </coordinateSystem.worldSystem>

		// <drawing>
		else if (name.equals("DRAWING__SWE_ELEMENT_STYLE")) {
			RuntimeParams.DRAWING__SWE_ELEMENT_STYLE = getIntValue(value);
		}

		else if (name.equals("DRAWING__FILL_COLOR__LABELS")) {
			RuntimeParams.DRAWING__FILL_COLOR__LABELS = getIntValue(value);
		}

		else if (name.equals("DRAWING__STYLE2__ALPHA")) {
			RuntimeParams.DRAWING__STYLE2__ALPHA = getIntValue(value);
		}

		else if (name.equals("DRAWING__SPHERE_SIZE___BIG")) {
			RuntimeParams.DRAWING__SPHERE_SIZE___BIG = getIntValue(value);
		}

		else if (name.equals("DRAWING__SPHERE_SIZE___MIDDLE")) {
			RuntimeParams.DRAWING__SPHERE_SIZE___MIDDLE = getIntValue(value);
		}

		else if (name.equals("DRAWING__SPHERE_SIZE___SMAL")) {
			RuntimeParams.DRAWING__SPHERE_SIZE___SMAL = getIntValue(value);
		}

		else if (name.equals("DRAWING__CONE_SIZE")) {
			RuntimeParams.DRAWING__CONE_SIZE = getIntValue(value);
		}

		else if (name.equals("DRAWING__TEXT_ENABLE")) {
			RuntimeParams.DRAWING__TEXT_ENABLE = getIntValue(value);
		}
		// </drawing>

		// <example>
		else if (name.equals("EXAMPLE__NUMBER")) {
			RuntimeParams.EXAMPLE__NUMBER = getIntValue(value);
		} else if (name.equals("EXAMPLE__ASSEMBLER_MODE")) {
			RuntimeParams.EXAMPLE__ASSEMBLER_MODE = getIntValue(value);
		}
		// </example>

		// <gfx.camera>
		else if (name.equals("CAMERA__USE_PEASY_CAM")) {
			RuntimeParams.CAMERA__USE_PEASY_CAM = getBooleanValue(value);
		} else if (name.equals("CAMERA__NO_CAM")) {
			RuntimeParams.CAMERA__NO_CAM = getBooleanValue(value);
		}
		// </gfx.camera>

		// <gfx.util>
		else if (name.equals("CONE_DRAWER__CONE_DETAIL")) {
			RuntimeParams.CONE_DRAWER__CONE_DETAIL = getIntValue(value);
		}
		// </gfx.util>

		// <logging>
		else if (name.equals("LOGGING__LOG_FRAME_WHEN_INTERVAL_IS_REACHED")) {
			RuntimeParams.LOGGING__LOG_FRAME_WHEN_INTERVAL_IS_REACHED = getBooleanValue(value);
		} else if (name
				.equals("LOGGING__INTERVAL_THAT_MUST_BE_REACHED_TO_LOG_FRAME")) {
			RuntimeParams.LOGGING__INTERVAL_THAT_MUST_BE_REACHED_TO_LOG_FRAME = getIntValue(value);
		}
		// </logging>

		// <logging.GFX_Object>
		else if (name.equals("GFX_OBJECT__LOG_CONSTRUCTOR_RESULT")) {
			RuntimeParams.GFX_OBJECT__LOG_CONSTRUCTOR_RESULT = getBooleanValue(value);
		} else if (name.equals("GFX_OBJECT__LOG_ADD_ELEMENTS_RESULT")) {
			RuntimeParams.GFX_OBJECT__LOG_ADD_ELEMENTS_RESULT = getBooleanValue(value);
		}

		else if (name.equals("GFX_OBJECT__LOG_CHANGE_FIELDS_RESULT")) {
			RuntimeParams.GFX_OBJECT__LOG_CHANGE_FIELDS_RESULT = getBooleanValue(value);
		}

		else if (name.equals("GFX_OBJECT__LOG_ARRANGEMENT_RESULT")) {
			RuntimeParams.GFX_OBJECT__LOG_ARRANGEMENT_RESULT = getBooleanValue(value);
		} else if (name.equals("GFX_OBJECT__LOG_DRAWING_RESULT")) {
			RuntimeParams.GFX_OBJECT__LOG_DRAWING_RESULT = getBooleanValue(value);
		}
		// </logging.GFX_Object>

		// <model>
		else if (name.equals("MODEL__EXISTING_XML_FILE")) {
			RuntimeParams.MODEL__EXISTING_XML_FILE = value;
		} else if (name.equals("MODEL__PATH_TO_SOFTWARE_INPUT_ROOT_FOLDER")) {
			RuntimeParams.MODEL__PATH_TO_SOFTWARE_INPUT_ROOT_FOLDER = value;
		} else if (name.equals("MODEL__USE_ABSOLUTE_PATH")) {
			RuntimeParams.MODEL__USE_ABSOLUTE_PATH = getBooleanValue(value);
		} else if (name.equals("MODEL__USE_EXISTING_STRING")) {
			RuntimeParams.MODEL__USE_EXISTING_STRING = getBooleanValue(value);
		} else if (name.equals("MODEL__USE_EXISTING_XML_FILE")) {
			RuntimeParams.MODEL__USE_EXISTING_XML_FILE = getBooleanValue(value);
		}

		else if (name.equals("MODEL__RELATIVE_PATH_TO_OUTPUT_XML")) {
			RuntimeParams.MODEL__RELATIVE_PATH_TO_OUTPUT_XML = value;
		}

		// </model>

		// <navi>
		else if (name.equals("NAVI__ONLY_ON_NODES")) {
			RuntimeParams.NAVI__ONLY_ON_NODES = getBooleanValue(value);
		}
		// </navi>

		// <parser>
		else if (name.equals("PARSER__READ_CLASSES")) {
			RuntimeParams.PARSER__READ_CLASSES = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_METHODS")) {
			RuntimeParams.PARSER__READ_METHODS = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_FIELDS")) {
			RuntimeParams.PARSER__READ_FIELDS = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_LINES_OF_CODE")) {
			RuntimeParams.PARSER__READ_LINES_OF_CODE = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_NAMES")) {
			RuntimeParams.PARSER__READ_NAMES = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_CLASS_ATTRIBUTES")) {
			RuntimeParams.PARSER__READ_CLASS_ATTRIBUTES = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_METHOD_ATTRIBUTES")) {
			RuntimeParams.PARSER__READ_METHOD_ATTRIBUTES = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_FIELD_ATTRIBUTES")) {
			RuntimeParams.PARSER__READ_FIELD_ATTRIBUTES = getBooleanValue(value);
		} else if (name.equals("PARSER__READ_SIZE_IN_BYTES")) {
			RuntimeParams.PARSER__READ_SIZE_IN_BYTES = getBooleanValue(value);
		}
		// </parser>

		// <processing_sketch>
		else if (name.equals("SKETCH__INITIAL_APPLET_WIDTH")) {
			RuntimeParams.SKETCH__INITIAL_APPLET_WIDTH = getIntValue(value);
		} else if (name.equals("SKETCH__INITIAL_APPLET_HEIGHT")) {
			RuntimeParams.SKETCH__INITIAL_APPLET_HEIGHT = getIntValue(value);

		} else if (name.equals("SKETCH__BACKGROUND_COLOR")) {
			RuntimeParams.SKETCH__BACKGROUND_COLOR = getIntValue(value);
		}

		else if (name.equals("SKETCH__ENABLE_SMOOTHING")) {
			RuntimeParams.SKETCH__ENABLE_SMOOTHING = getBooleanValue(value);
		} else if (name.equals("SKETCH__FRAME_RATE")) {
			RuntimeParams.SKETCH__FRAME_RATE = getIntValue(value);
		}
		// </processing_sketch>

		// <show>
		else if (name.equals("SHOW__WORLD_COORDINATE_SYSTEM")) {
			RuntimeParams.SHOW__WORLD_COORDINATE_SYSTEM = getBooleanValue(value);
		} else if (name.equals("SHOW__RELATIVE_COORDINATE_SYSTEMS")) {
			RuntimeParams.SHOW__RELATIVE_COORDINATE_SYSTEMS = getBooleanValue(value);
		} else if (name.equals("SHOW__LOCAL_COORDINATE_SYSTEMS")) {
			RuntimeParams.SHOW__LOCAL_COORDINATE_SYSTEMS = getBooleanValue(value);
		}

		else if (name.equals("SHOW__RELATIVE_000_BOX")) {
			RuntimeParams.SHOW__RELATIVE_000_BOX = getBooleanValue(value);
		} else if (name.equals("SHOW__RELATIVE_111_BOX")) {
			RuntimeParams.SHOW__RELATIVE_111_BOX = getBooleanValue(value);
		} else if (name.equals("SHOW__RELATIVE_BOUNDING_BOX")) {
			RuntimeParams.SHOW__RELATIVE_BOUNDING_BOX = getBooleanValue(value);
		} else if (name.equals("SHOW__RELATIVE_BOUNDING_SPHERE")) {
			RuntimeParams.SHOW__RELATIVE_BOUNDING_SPHERE = getBooleanValue(value);
		} else if (name.equals("SHOW__LOCAL_BOUNDING_BOX")) {
			RuntimeParams.SHOW__LOCAL_BOUNDING_BOX = getBooleanValue(value);
		} else if (name.equals("SHOW__ROTATION_OFFSET_BOX")) {
			RuntimeParams.SHOW__ROTATION_OFFSET_BOX = getBooleanValue(value);
		} else if (name.equals("SHOW__CIRCLE_LAYOUT_TRACE")) {
			RuntimeParams.SHOW__CIRCLE_LAYOUT_TRACE = getBooleanValue(value);
		} else if (name.equals("SHOW__CIRCLE_LAYOUT_TRACE_CIRCLE")) {
			RuntimeParams.SHOW__CIRCLE_LAYOUT_TRACE_CIRCLE = getBooleanValue(value);
		} else if (name.equals("SHOW__2D_OVERLAY")) {
			RuntimeParams.SHOW__2D_OVERLAY = getBooleanValue(value);
		} else if (name.equals("SHOW__EDGES")) {
			RuntimeParams.SHOW__EDGES = getBooleanValue(value);
		} else if (name.equals("SHOW__3D_EDGES")) {
			RuntimeParams.SHOW__3D_EDGES = getBooleanValue(value);
		}

		else if (name.equals("SHOW__SCENE_BOUNDING")) {
			RuntimeParams.SHOW__SCENE_BOUNDING = getBooleanValue(value);
		} else if (name.equals("SHOW__LAYOUT_BOUNDING")) {
			RuntimeParams.SHOW__LAYOUT_BOUNDING = getBooleanValue(value);
		} else if (name.equals("SHOW__SWE_ELEMENT_BOUNDING")) {
			RuntimeParams.SHOW__SWE_ELEMENT_BOUNDING = getBooleanValue(value);
		}

		else if (name.equals("SHOW__CURRENT")) {
			RuntimeParams.SHOW__CURRENT = getBooleanValue(value);
		}

		else if (name.equals("SHOW__BLINKING_INTERVAL")) {
			RuntimeParams.SHOW__BLINKING_INTERVAL = getIntValue(value);
		}

		else if (name.equals("SHOW__SWE_ELEMENTS")) {
			RuntimeParams.SHOW__SWE_ELEMENTS = getBooleanValue(value);
		}

		else if (name.equals("SHOW__LABELS")) {
			RuntimeParams.SHOW__LABELS = getBooleanValue(value);
		}
		// </show>
	}

	public static void updateParamsFromFile() {
		if (RuntimeParams.release == RP.ReleaseEnum.PROTOTYPE
				&& LocalWorkspaceConstants.USE_RUNTIME_PARAMS_TXT) {
			readFile();
		}
	}
}
